#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <unistd.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <memory.h>  
#include <linux/tcp.h>
#include <linux/ip.h>
//#include <net/sock.h>

#include "cmd_thread.h"
#include "libsapi_common.h"
#include "libsapi_video.h"
#include "drvsapi_video.h"

extern pthread_mutex_t vctrl_mutex;
extern pthread_t       vctrl_thread;
extern pthread_cond_t  vctrl_start_ready;
extern pthread_cond_t  vctrl_over_ready;

extern pthread_mutex_t net_mutex;
extern pthread_cond_t  net_ready;
extern pthread_t       net_thread;

struct vctrl_params params;

int cmd_socket_process(int sockfd)
{
	struct vctrl_params *pcp = &params;
	int len = 0;
	int ret = 0;

	len = recv(sockfd, (char*)pcp, sizeof(struct vctrl_params), 0);
	if (len<0) {
		fprintf(stderr, "server recv cmd params error\n");
		exit(1);
	}

	printf("server recv intf  =%d\n", pcp->intf);
	printf("server recv cmd   =%x\n", pcp->cmd);

	/*wakeup vctrl thread to process revceived cmd*/
	pthread_cond_signal(&vctrl_start_ready);

	/*wait vctrl thread process over*/
	ret = pthread_cond_wait(&vctrl_over_ready, &vctrl_mutex);
	if (ret==0) {
		printf("vctrl thread wait sucess\n");
	} else {
		printf("vctrl thread wait failed\n");
		return 0;
	}

	/*send process result to client*/
	len = send(sockfd, (char*)pcp, sizeof(struct vctrl_params), 0);
	if (len<0) {
		fprintf(stderr, "server send cmd params error\n");
		exit(1);
	}

	printf("server send intf  =%d\n", pcp->intf);
	printf("server send cmd   =%d\n", pcp->cmd);

	return 0;
}

int cmd_socket_server_monitor(int portnum)
{
	int sockfd=0, new_fd=0;
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	int sin_size;
	int ret=0;

	memset(&client_addr, 0, sizeof(client_addr));
	memset(&server_addr, 0, sizeof(server_addr));

	ret = sockfd=socket(AF_INET, SOCK_STREAM, 0);
	if (ret==-1) {
		fprintf(stderr,"Socket error:%s\n\a", strerror(errno));
		exit(1);
	}

	bzero(&server_addr, sizeof(struct sockaddr_in));
	server_addr.sin_family      = AF_INET;
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	server_addr.sin_port        = htons(portnum);
	ret = bind(sockfd, (struct sockaddr*)(&server_addr), sizeof(struct sockaddr));
	if (ret==-1) {
		fprintf(stderr,"Bind error:%s\n\a", strerror(errno));
		exit(1);
	}

	ret = listen(sockfd, 5);
	if (ret==-1) {
		fprintf(stderr,"Listen error:%s\n\a", strerror(errno));
		exit(1);
	}

	while (1) {
		
		sin_size = sizeof(struct sockaddr_in);
		new_fd=accept(sockfd, (struct sockaddr *)(&client_addr), &sin_size);
		if (new_fd==-1) {
			fprintf(stderr, "Accept error:%s\n\a", strerror(errno));
			continue;
		}
		fprintf(stderr, "server get connect from %s, port %d(%d), socket %d\n",
			inet_ntoa(client_addr.sin_addr),
			ntohs(client_addr.sin_port),
			client_addr.sin_port,
			new_fd);

		pthread_mutex_lock(&net_mutex);
		cmd_socket_process(new_fd);
		pthread_mutex_unlock(&net_mutex);

		close(new_fd);
	}

	close(sockfd);
	exit(0);
}

void* net_function()
{
	printf("i am net function\n");

	cmd_socket_server_monitor(2020);

	pthread_exit(NULL);
}
